// 当前项目（包）的入口文件

// 1.加载 http 模块
var http = require('http')
var fs = require('fs')
var path = require('path')
var mime = require('mime')
var url = require('url')
var querystring = require('querystring')
var _ = require('underscore')
var dbPath = path.join(__dirname, 'data', 'data.json')
// 2.创建服务
http.createServer(function(req, res){
	// 要在这里写大量的代码
	
	res.render = function(filename, tplData){
		fs.readFile(filename, 'utf8', function(err, data){
			if (err) {
				throw err
			}
			if (tplData) {
				var fn = _.template(data)
				data = fn(tplData)
			}
			res.setHeader('Content-Type', mime.getType(filename))
			res.end(data)
		})
	}
	

	// 设计路由
	// 当用户请求 / 或 /index 时，显示新闻列表 - get 请求
	// 当用户请求 /item 时，显示新闻详情 - get 请求
	// 当用户请求 /submit 时，显示添加新闻页面 - get 请求
	// 当用户请求 /add 时，将用户提交的新闻保存到 data.json 文件中 - get 请求
	// 当用户请求 /add 时，将用户提交的新闻保存到 data.json 文件中 - post 请求
	// 将用户请求的url和method转换为小写字母
	req.url = req.url.toLowerCase()
	req.method = req.method.toLowerCase()

	var urlObj = url.parse(req.url, true)
	var pathname = urlObj.pathname

	

	// 如果用户请求是以 /resources 开头，并且是 get 请求，就认为用户是要请求静态资源
	if(pathname.startsWith('/resources') && req.method === 'get'){
		res.render(path.join(__dirname, pathname))
	}
	// 先根据用户请求的路径（路由），将对应的HTML页面显示出来
	else if (pathname === '/' || pathname === '/index' && req.method === 'get') {
		// 1.读取 index.html 并返回
		newReadFile(dbPath, function(list){
			res.render(path.join(__dirname, 'views', 'index.html'), {list:list})
		})
	}else if(pathname === '/submit' && req.method === 'get'){
		// 读取 submmit.html 并返回
		res.render(path.join(__dirname, 'views', 'submit.html'))
	}else if(pathname === '/item' && req.method === 'get'){
		// 读取 details.html 并返回
		newReadFile(dbPath, function(list){
			if (list.length <= 0) {
				return res.end('No such item.')
			}
			var id = parseInt(urlObj.query.id)
			var model = null
			for (var i = 0; i < list.length; i++) {
				if (list[i].id === id) {
					model = list[i]
					break
				}
			}
			if ( ! model) {
				return res.end('No such item.')
			}
			res.render(path.join(__dirname, 'views', 'details.html'), {item : model})
		})
	}else if(pathname === '/add' && req.method === 'get'){
		// 读取 get 方法提交一条新闻
		newReadFile(dbPath, function(list){
			var obj = urlObj.query
			obj.id = list.length

			list.push(obj)
			newWriteFile(JSON.stringify(list), function(){
				res.statusCode = 302
				res.statusMessage = 'Found'
				res.setHeader('Location', '/')
				res.end()
			})
		})
	}else if(pathname === '/add' && req.method === 'post'){
		// 读取 post 方法提交一条新闻
		newReadFile(dbPath, function(list){
			postBody(req, function(postBody){
				postBody.id = list.length
				list.push(postBody)

				newWriteFile(JSON.stringify(list), function(){
					res.statusCode = 302
					res.statusMessage = 'Found'
					res.setHeader('Location', '/')
					res.end()
				})
			})
		})
	}else{
		res.writeHead(404, 'Not Found', {
			'Content-Type' : 'text/html;charset=utf-8'
		})
		res.end('404, Page Not Found')
	}
}).listen(3000, function(){
	console.log('server running 3000...')
})

function postBody(req, callback){
	// 声明一个数组，用户保存用户每次提交过来的数据
	var array = []
	req.on('data', function(chunk){
		// 此处的 chunk 参数，就是浏览器本次提交过来的一部分数据
		// chunk的数据类型是 Buffer (chunk就是一个Buffer对象)
		array.push(chunk)
	})
	// 监听 request 对象的 end 事件
	// 当 end 事件被触发的时候，表示所有数据都已经提交完毕了
	req.on('end', function(){
		// 在这个事件中只要把 array 中的所有数据汇总起来就好了
		// 把 array 中的每个buffer对象，集合起来转换为一个buffer对象
		var postBody = Buffer.concat(array)
		postBody = postBody.toString('utf8')
		postBody = querystring.parse(postBody)

		callback(postBody)
	})
}

function newReadFile(filename, callback){
	fs.readFile(filename, 'utf8', function(err, data){
		// 因为第一次访问网站，data.json文件本身就不存在，所以肯定是有错误的
			// 但是这种错误，我们并不认为是网站出错了，所以不需要抛出异常
		if(err && err.code != 'ENOENT'){
			throw err
		}
		var list = JSON.parse(data || '[]')
		callback(list)
	})
}

function newWriteFile(data, callback){
	fs.writeFile(dbPath, data, function(err){
		if (err) {
			throw err
		}
		callback()
	})
}